package controller

import (
	"bluebell/logic"
	"bluebell/models"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"go.uber.org/zap"
	"strconv"
)

// CreatePostHandler
// @Tags PantheonApi
// @Summary 创建帖子
// @Schemes
// @Description	Post 请求, 发送 json 类型的数据, 参数在消息体中
// @Accept json
// @Produce json
// @Param	postCreateMessage body  models.Post  true "帖子信息"
// @Success 200 {string} json{"code","message","data"}
// @Router	/api/Pantheon/post [post]
func CreatePostHandler(c *gin.Context){
	// 1、获取参数及校验参数
	var post models.Post
	if err := c.ShouldBindJSON(&post);err != nil{
		zap.L().Debug("c.ShouldBindJSON(post) err", zap.Any("err", err))
		zap.L().Error("create post with invalid parm")
		ResponseErrorWithMsg(c, CodeInvalidParams, err.Error())
		return
	}
	// 获取作者ID，当前请求的UserID(从c取到当前发请求的用户ID)
	userID, err := getCurrentUserId(c)
	if err != nil {
		zap.L().Error("GetCurrentUserID() failed", zap.Error(err))
		ResponseError(c, CodeNotLogin)
		return
	}
	post.AuthorId = userID
	// 2、创建帖子
	err = logic.CreatePost(&post)
	if err != nil {
		zap.L().Error("logic.CreatePost failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
		return
	}
	// 3、返回响应
	ResponseSuccess(c, nil)
}

// PostListDetailHandler
// @Tags PostApi
// @Summary 分页获取帖子列表
// @Schemes
// @Description	Get 请求, 发送 json 类型的数据, 参数在消息体中
// @Accept json
// @Produce json
// @Param	page query int true "页数"
// @Param	size query  int true "size"
// @Success 200 {string} json{"code","message","data"}
// @Router	/api/post/posts [get]
func PostListDetailHandler(c *gin.Context)  {
	// 获取分页参数
	page,size := getPageInfo(c)
	// 获取数据
	data,err := logic.GetPostDetailList(page,size)
	if err != nil{
		ResponseError(c, CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
}

// PostDetailHandler
// @Tags PostApi
// @Summary 通过post_id获取帖子的信息
// @Schemes
// @Description	Get 请求, 发送 json 类型的数据, 参数在消息体中
// @Accept json
// @Produce json
// @Param	post_id query int true "帖子id"
// @Success 200 {string} json{"code","message","data"}
// @Router	/api/post/post [get]
func PostDetailHandler(c *gin.Context){
	// 1、获取参数(从URL中获取post_id)
	postIdStr := c.Param("post_id")
	postId,err := strconv.ParseInt(postIdStr, 10, 64)
	if err != nil {
		zap.L().Error("get post detail with invalid param", zap.Error(err))
		ResponseError(c, CodeInvalidParams)
	}

	// 2、根据post_id获取帖子数据(查数据库)
	post, err := logic.GetPostById(postId)
	if err != nil {
		zap.L().Error("logic.GetPostById() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
	}

	// 3、返回响应
	ResponseSuccess(c, post)
}

// PostListSortHandler
// @Tags PostApi
// @Summary 升级版帖子列表接口：按 创建时间 或者 分数排序
// @Schemes
// @Description	Get 请求, 发送 json 类型的数据, 参数在消息体中
// @Accept json
// @Produce json
// @Param	ParamPostList body models.ParamPostList true "帖子id"
// @Success 200 {string} json{"code","message","data"}
// @Router	/api/post/posts2 [get]
func PostListSortHandler(c *gin.Context)  {
	// GET请求参数(query string)： /api/v1/posts2?page=1&size=10&order=time
	p := &models.ParamPostList{}
	if err := c.ShouldBindQuery(&p);err != nil{
		// 请求参数有误，直接返回响应
		zap.L().Error("PostListSortHandler with invalid param",zap.Error(err))
		// 判断err是不是 validator.ValidationErrors类型的errors
		errs,ok := err.(validator.ValidationErrors)
		if !ok{
			// 非validator.ValidationErrors类型错误直接返回
			ResponseErrorWithMsg(c, CodeInvalidParams, errs.Error())
			return
		}
		// validator.ValidationErrors类型错误则进行翻译
		ResponseErrorWithMsg(c, CodeInvalidParams, removeTopStruct(errs.Translate(trans)))
		return
	}

	// 获取数据
	data,err := logic.GetSortPostListByCommunityId(p)
	if err != nil{
		ResponseError(c, CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
}

// PostSearchHandler
// @Tags PostApi
// @Summary 搜索业务-搜索帖子
// @Schemes
// @Description	Get 请求, 发送 json 类型的数据, 参数在消息体中
// @Accept json
// @Produce json
// @Param	ParamPostList body models.ParamPostList true "帖子id"
// @Success 200 {string} json{"code","message","data"}
// @Router	/api/post/search [get]
func PostSearchHandler(c *gin.Context){
	p := &models.ParamPostList{}
	if err := c.ShouldBindQuery(&p);err != nil{
		// 请求参数有误，直接返回响应
		zap.L().Error("PostSearchHandler with invalid params",zap.Error(err))
		// 判断err是不是 validator.ValidationErrors类型的errors
		errs,ok := err.(validator.ValidationErrors)
		if !ok{
			// 非validator.ValidationErrors类型错误直接返回
			ResponseErrorWithMsg(c, CodeInvalidParams, errs.Error())
			return
		}
		// validator.ValidationErrors类型错误则进行翻译
		ResponseErrorWithMsg(c, CodeInvalidParams, removeTopStruct(errs.Translate(trans)))
		return
	}

	// 获取数据
	data, err := logic.PostSearch(p)
	if err != nil {
		ResponseError(c, CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
}